# app.py
from flask import Flask, render_template_string, jsonify, request
import random
import json

app = Flask(__name__)

class SnakeGame:
    def __init__(self):
        self.reset()
    
    def reset(self):
        self.width = 20
        self.height = 20
        self.snake = [(10, 10)]
        self.direction = (1, 0)  # 向右
        self.food = self.generate_food()
        self.score = 0
        self.game_over = False
    
    def generate_food(self):
        while True:
            food = (random.randint(0, self.width-1), random.randint(0, self.height-1))
            if food not in self.snake:
                return food
    
    def move(self):
        if self.game_over:
            return
        
        head_x, head_y = self.snake[0]
        dir_x, dir_y = self.direction
        new_head = ((head_x + dir_x) % self.width, (head_y + dir_y) % self.height)
        
        if new_head in self.snake:
            self.game_over = True
            return
        
        self.snake.insert(0, new_head)
        
        if new_head == self.food:
            self.score += 10
            self.food = self.generate_food()
        else:
            self.snake.pop()
    
    def change_direction(self, new_direction):
        # 防止反向移动
        current_x, current_y = self.direction
        new_x, new_y = new_direction
        
        if (current_x, current_y) != (-new_x, -new_y):
            self.direction = (new_x, new_y)

game = SnakeGame()

@app.route('/')
def index():
    return render_template_string('''<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>贪吃蛇游戏</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            min-height: 100vh;
            margin: 0;
            background: #2c3e50;
            color: white;
        }
        .game-container {
            text-align: center;
        }
        #gameCanvas {
            border: 2px solid #34495e;
            background: #1a252f;
        }
        .controls {
            margin: 20px 0;
        }
        button {
            padding: 10px 20px;
            margin: 5px;
            background: #3498db;
            color: white;
            border: none;
            border-radius: 5px;
            cursor: pointer;
        }
        .score {
            font-size: 20px;
            margin: 10px 0;
        }
        .game-over {
            color: #e74c3c;
            font-size: 24px;
            margin: 10px 0;
        }
    </style>
</head>
<body>
    <div class="game-container">
        <h1>贪吃蛇游戏</h1>
        <div class="score">得分: <span id="score">0</span></div>
        <div id="gameOver" class="game-over"></div>
        <canvas id="gameCanvas" width="400" height="400"></canvas>
        <div class="controls">
            <button onclick="resetGame()">重新开始</button>
            <button onclick="togglePause()">暂停/继续</button>
        </div>
        <div class="instructions">
            <p>使用方向键或 WASD 控制蛇的移动</p>
        </div>
    </div>

    <script>
        const canvas = document.getElementById('gameCanvas');
        const ctx = canvas.getContext('2d');
        const scoreElement = document.getElementById('score');
        const gameOverElement = document.getElementById('gameOver');
        
        const GRID_SIZE = 20;
        const GAME_SPEED = 150;
        
        let gameState = {};
        let isPaused = false;
        let gameLoop;

        // 修复：正确的方向映射
        const DIRECTIONS = {
            'ArrowUp': [0, -1],
            'ArrowDown': [0, 1],
            'ArrowLeft': [-1, 0],
            'ArrowRight': [1, 0],
            'KeyW': [0, -1],
            'KeyS': [0, 1],
            'KeyA': [-1, 0],
            'KeyD': [1, 0]
        };

        // 修复：改进的键盘事件处理
        document.addEventListener('keydown', (event) => {
            console.log('按键按下:', event.code); // 调试用
            
            if (DIRECTIONS[event.code]) {
                event.preventDefault(); // 防止页面滚动
                changeDirection(DIRECTIONS[event.code]);
            }
            
            // 空格键暂停
            if (event.code === 'Space') {
                event.preventDefault();
                togglePause();
            }
        });

        // 修复：确保焦点在canvas上
        canvas.setAttribute('tabindex', '0');
        canvas.style.outline = 'none';
        canvas.addEventListener('click', () => {
            canvas.focus();
        });

        async function fetchGameState() {
            try {
                const response = await fetch('/game/state');
                gameState = await response.json();
                updateDisplay();
            } catch (error) {
                console.error('获取游戏状态失败:', error);
            }
        }

        async function moveSnake() {
            if (isPaused || gameState.game_over) return;
            
            try {
                const response = await fetch('/game/move', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                });
                gameState = await response.json();
                updateDisplay();
            } catch (error) {
                console.error('移动失败:', error);
            }
        }

        async function changeDirection(direction) {
            if (isPaused || gameState.game_over) return;
            
            console.log('改变方向:', direction); // 调试用
            
            try {
                const response = await fetch('/game/direction', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    body: JSON.stringify({ direction: direction })
                });
                
                const result = await response.json();
                console.log('方向改变结果:', result); // 调试用
                
            } catch (error) {
                console.error('改变方向失败:', error);
            }
        }

        async function resetGame() {
            try {
                const response = await fetch('/game/reset', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                });
                gameState = await response.json();
                isPaused = false;
                updateDisplay();
                
                // 重新开始游戏循环
                if (gameLoop) {
                    clearInterval(gameLoop);
                }
                gameLoop = setInterval(moveSnake, GAME_SPEED);
                
            } catch (error) {
                console.error('重置游戏失败:', error);
            }
        }

        function togglePause() {
            isPaused = !isPaused;
            if (!isPaused) {
                moveSnake(); // 立即执行一次移动
            }
        }

        function updateDisplay() {
            // 清空画布
            ctx.fillStyle = '#1a252f';
            ctx.fillRect(0, 0, canvas.width, canvas.height);
            
            // 绘制网格
            ctx.strokeStyle = '#2c3e50';
            ctx.lineWidth = 0.5;
            for (let x = 0; x < canvas.width; x += GRID_SIZE) {
                ctx.beginPath();
                ctx.moveTo(x, 0);
                ctx.lineTo(x, canvas.height);
                ctx.stroke();
            }
            for (let y = 0; y < canvas.height; y += GRID_SIZE) {
                ctx.beginPath();
                ctx.moveTo(0, y);
                ctx.lineTo(canvas.width, y);
                ctx.stroke();
            }
            
            // 绘制食物
            if (gameState.food) {
                const [foodX, foodY] = gameState.food;
                ctx.fillStyle = '#e74c3c';
                ctx.beginPath();
                ctx.arc(
                    foodX * GRID_SIZE + GRID_SIZE / 2,
                    foodY * GRID_SIZE + GRID_SIZE / 2,
                    GRID_SIZE / 2 - 1,
                    0,
                    Math.PI * 2
                );
                ctx.fill();
            }
            
            // 绘制蛇
            if (gameState.snake) {
                gameState.snake.forEach((segment, index) => {
                    const [x, y] = segment;
                    
                    if (index === 0) {
                        ctx.fillStyle = '#27ae60'; // 蛇头
                    } else {
                        ctx.fillStyle = '#2ecc71'; // 蛇身
                    }
                    
                    ctx.fillRect(
                        x * GRID_SIZE + 1,
                        y * GRID_SIZE + 1,
                        GRID_SIZE - 2,
                        GRID_SIZE - 2
                    );
                });
            }
            
            // 更新分数
            scoreElement.textContent = gameState.score || 0;
            
            // 显示游戏结束信息
            if (gameState.game_over) {
                gameOverElement.textContent = '游戏结束！点击重新开始';
            } else {
                gameOverElement.textContent = '';
            }
        }

        // 初始化游戏
        async function initGame() {
            await fetchGameState();
            canvas.focus(); // 确保canvas获得焦点
            gameLoop = setInterval(moveSnake, GAME_SPEED);
        }

        // 启动游戏
        initGame();
    </script>
</body>
</html>''')

@app.route('/game/state')
def get_game_state():
    return jsonify({
        'snake': game.snake,
        'food': game.food,
        'score': game.score,
        'game_over': game.game_over,
        'direction': game.direction,  # 添加方向信息
        'width': game.width,
        'height': game.height
    })

@app.route('/game/move', methods=['POST'])
def move_snake():
    game.move()
    return get_game_state()

@app.route('/game/direction', methods=['POST'])
def change_direction():
    try:
        data = request.get_json()
        if data and 'direction' in data:
            direction = tuple(data['direction'])
            game.change_direction(direction)
            return jsonify({'success': True, 'new_direction': game.direction})
        return jsonify({'success': False, 'error': 'Invalid data'})
    except Exception as e:
        return jsonify({'success': False, 'error': str(e)})

@app.route('/game/reset', methods=['POST'])
def reset_game():
    game.reset()
    return get_game_state()

if __name__ == '__main__':
    app.run(host="0.0.0.0",debug=True,port=8082)